package com.xiaoh.dormitoryrepairreportbackend.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaoh.dormitoryrepairreportbackend.annotation.RequireRole;
import com.xiaoh.dormitoryrepairreportbackend.common.BaseResponse;
import com.xiaoh.dormitoryrepairreportbackend.common.ErrorCode;
import com.xiaoh.dormitoryrepairreportbackend.constant.UserConstant;
import com.xiaoh.dormitoryrepairreportbackend.exception.BusinessException;
import com.xiaoh.dormitoryrepairreportbackend.model.dto.common.PageResponse;
import com.xiaoh.dormitoryrepairreportbackend.model.dto.skill.*;
import com.xiaoh.dormitoryrepairreportbackend.model.entity.GeneralUser;
import com.xiaoh.dormitoryrepairreportbackend.model.entity.MaintenanceSkill;
import com.xiaoh.dormitoryrepairreportbackend.model.entity.RepairCategory;
import com.xiaoh.dormitoryrepairreportbackend.service.GeneralUserService;
import com.xiaoh.dormitoryrepairreportbackend.service.MaintenanceSkillService;
import com.xiaoh.dormitoryrepairreportbackend.service.RepairCategoryService;
import com.xiaoh.dormitoryrepairreportbackend.utils.QueryUtils;
import com.xiaoh.dormitoryrepairreportbackend.utils.UserConverter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 维修工技能管理接口
 */
@RestController
@RequestMapping("/skill")
@Slf4j
@Tag(name = "技能管理", description = "维修工技能管理相关接口")
public class MaintenanceSkillController {

    @Resource
    private MaintenanceSkillService maintenanceSkillService;

    @Resource
    private GeneralUserService generalUserService;

    @Resource
    private RepairCategoryService repairCategoryService;

    /**
     * 添加维修工技能
     */
    @PostMapping("/add")
    @Operation(summary = "添加维修工技能", description = "管理员为维修工添加技能")
    @RequireRole(UserConstant.UserType.ADMIN)
    public BaseResponse<Boolean> addMaintenanceSkill(@Valid @RequestBody MaintenanceSkillAddRequest addRequest, HttpServletRequest request) {
        if (addRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Long userId = addRequest.getUserId();
        Integer categoryId = addRequest.getCategoryId();

        // 验证用户是否存在且为维修工
        GeneralUser user = generalUserService.getById(userId);
        if (user == null) {
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        if (UserConstant.UserType.MAINTENANCE != user.getUserType()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "只能为维修工添加技能");
        }

        // 验证维修类别是否存在且启用
        RepairCategory category = repairCategoryService.getById(categoryId);
        if (category == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "维修类别不存在");
        }
        if (category.getIsActive() == 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "维修类别已禁用");
        }

        boolean result = maintenanceSkillService.addMaintenanceSkill(userId, categoryId);
        return BaseResponse.success(result);
    }

    /**
     * 移除维修工技能
     */
    @PostMapping("/remove")
    @Operation(summary = "移除维修工技能", description = "管理员移除维修工的技能")
    @RequireRole(UserConstant.UserType.ADMIN)
    public BaseResponse<Boolean> removeMaintenanceSkill(@Valid @RequestBody MaintenanceSkillRemoveRequest removeRequest, HttpServletRequest request) {
        if (removeRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Long userId = removeRequest.getUserId();
        Integer categoryId = removeRequest.getCategoryId();

        // 验证用户是否存在且为维修工
        GeneralUser user = generalUserService.getById(userId);
        if (user == null) {
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        if (UserConstant.UserType.MAINTENANCE != user.getUserType()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "只能移除维修工的技能");
        }

        boolean result = maintenanceSkillService.removeMaintenanceSkill(userId, categoryId);
        return BaseResponse.success(result);
    }

    /**
     * 查询维修工技能列表
     * 使用游标分页保持性能，同时返回完整分页信息
     */
    @PostMapping("/list")
    @Operation(summary = "查询维修工技能列表", description = "分页查询维修工技能信息，返回完整分页信息（总记录数、总页数等）")
    @RequireRole(UserConstant.UserType.ADMIN)
    public BaseResponse<PageResponse<MaintenanceSkillResponse>> listMaintenanceSkills(@Valid @RequestBody MaintenanceSkillQueryRequest queryRequest, HttpServletRequest request) {
        if (queryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 构建查询条件
        QueryWrapper<MaintenanceSkill> queryWrapper = new QueryWrapper<>();

        // 1. 根据维修工账号和昵称查询维修工用户ID列表
        List<Long> userIds = new ArrayList<>();
        if (StrUtil.isNotBlank(queryRequest.getAccountName()) || StrUtil.isNotBlank(queryRequest.getNickName())) {
            QueryWrapper<GeneralUser> userQueryWrapper = new QueryWrapper<>();
            // 只查询维修工类型的用户
            userQueryWrapper.eq("user_type", UserConstant.UserType.MAINTENANCE);

            // 添加账号模糊查询条件
            QueryUtils.addLikeCondition(userQueryWrapper, "account_name", queryRequest.getAccountName());
            // 添加昵称模糊查询条件
            QueryUtils.addLikeCondition(userQueryWrapper, "nick_name", queryRequest.getNickName());

            List<GeneralUser> users = generalUserService.list(userQueryWrapper);
            if (users.isEmpty()) {
                // 没有找到匹配的维修工，返回空列表
                return BaseResponse.success(PageResponse.empty(queryRequest.getCurrent(), queryRequest.getPageSize().longValue()));
            }
            userIds = users.stream().map(GeneralUser::getId).collect(Collectors.toList());
            queryWrapper.in("user_id", userIds);
        } else if (queryRequest.getUserId() != null) {
            // 如果没有账号和昵称条件，但有用户ID，则使用用户ID
            QueryUtils.addEqCondition(queryWrapper, "user_id", queryRequest.getUserId());
        }

        // 2. 添加维修类别ID查询条件
        String categoryName = queryRequest.getCategoryName();
        if (StrUtil.isNotBlank(categoryName)) {
            // 根据类别名称查询类别ID
            QueryWrapper<RepairCategory> categoryQueryWrapper = new QueryWrapper<>();
            categoryQueryWrapper.eq("category_name", categoryName);
            RepairCategory category = repairCategoryService.getOne(categoryQueryWrapper, false);
            QueryUtils.addEqCondition(queryWrapper, "category_id", category.getId());
        }

        // 3. 查询总记录数（不包含分页条件）
        QueryWrapper<MaintenanceSkill> countWrapper = QueryUtils.createCountQueryWrapper(queryWrapper);
        Long total = maintenanceSkillService.count(countWrapper);

        // 4. 添加排序和游标分页（由于MaintenanceSkill表没有id字段，使用created_at时间戳作为游标）
        queryWrapper.orderByAsc("created_at");

        // 使用created_at时间戳作为游标进行分页
        if (queryRequest.getLastId() != null) {
            // lastId在这里表示上一页最后一条记录的created_at时间戳
            queryWrapper.gt("created_at", new java.util.Date(queryRequest.getLastId()));
        }

        // 限制页面大小
        int pageSize = QueryUtils.validatePageSize(queryRequest.getPageSize());
        queryWrapper.last("LIMIT " + pageSize);

        List<MaintenanceSkill> skills = maintenanceSkillService.list(queryWrapper);

        // 转换为响应DTO - 不再进行去重，保留所有技能记录
        List<MaintenanceSkillResponse> responses = convertToSkillResponses(skills);

        // 获取下一页游标（使用最后一条记录的created_at时间戳）
        Long nextCursor = null;
        if (!skills.isEmpty()) {
            MaintenanceSkill lastSkill = skills.get(skills.size() - 1);
            nextCursor = lastSkill.getCreatedAt().toEpochSecond(ZoneOffset.UTC);
        }

        // 计算当前页码
        Long current = QueryUtils.calculateCurrentPage(queryRequest.getLastId(), queryRequest.getPageSize(), total);

        // 构建分页响应
        PageResponse<MaintenanceSkillResponse> pageResponse = PageResponse.of(responses, current, queryRequest.getPageSize().longValue(), total, nextCursor);
        return BaseResponse.success(pageResponse);
    }

    /**
     * 获取维修工的技能汇总
     */
    @GetMapping("/user/{userId}")
    @Operation(summary = "获取维修工技能汇总", description = "获取指定维修工的所有技能信息")
    @RequireRole(value = {UserConstant.UserType.ADMIN, UserConstant.UserType.MAINTENANCE}, allowSelf = true)
    public BaseResponse<UserSkillSummaryResponse> getUserSkillSummary(@PathVariable Long userId, HttpServletRequest request) {
        if (userId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户ID不能为空");
        }

        // 验证用户是否存在且为维修工
        GeneralUser user = generalUserService.getById(userId);
        if (user == null) {
            throw new BusinessException(ErrorCode.USER_NOT_EXIST);
        }
        if (UserConstant.UserType.MAINTENANCE != user.getUserType()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "只能查询维修工的技能");
        }

        // 获取用户技能
        List<Integer> categoryIds = maintenanceSkillService.getCategoryIdsByUserId(userId);

        UserSkillSummaryResponse response = new UserSkillSummaryResponse();

        // 设置用户基本信息
        response.setUserInfo(UserConverter.toUserResponse(user));

        // 设置技能信息
        List<UserSkillSummaryResponse.SkillCategoryInfo> skillInfos = new ArrayList<>();
        if (!categoryIds.isEmpty()) {
            List<RepairCategory> categories = repairCategoryService.listByIds(categoryIds);
            skillInfos = categories.stream().map(category -> {
                UserSkillSummaryResponse.SkillCategoryInfo skillInfo = new UserSkillSummaryResponse.SkillCategoryInfo();
                skillInfo.setCategoryId(category.getId());
                skillInfo.setCategoryName(category.getCategoryName());
                skillInfo.setCategoryDescription(category.getDescription());
                skillInfo.setIsActive(category.getIsActive());
                return skillInfo;
            }).collect(Collectors.toList());
        }
        response.setSkills(skillInfos);

        return BaseResponse.success(response);
    }

    /**
     * 获取所有维修工及其技能
     */
    @PostMapping("/all-maintenance-workers")
    @Operation(summary = "获取所有维修工及其技能", description = "获取所有维修工的技能汇总信息")
    @RequireRole(UserConstant.UserType.ADMIN)
    public BaseResponse<List<UserSkillSummaryResponse>> getAllMaintenanceWorkersWithSkills(HttpServletRequest request) {
        // 获取所有维修工
        QueryWrapper<GeneralUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("user_type", UserConstant.UserType.MAINTENANCE);
        List<GeneralUser> maintenanceUsers = generalUserService.list(userQueryWrapper);

        if (maintenanceUsers.isEmpty()) {
            return BaseResponse.success(new ArrayList<>());
        }

        // 获取所有技能信息
        List<MaintenanceSkill> allSkills = maintenanceSkillService.list();
        Map<Long, List<Integer>> userSkillMap = allSkills.stream()
                .collect(Collectors.groupingBy(
                        MaintenanceSkill::getUserId,
                        Collectors.mapping(MaintenanceSkill::getCategoryId, Collectors.toList())
                ));

        // 获取所有维修类别
        List<RepairCategory> allCategories = repairCategoryService.list();
        Map<Integer, RepairCategory> categoryMap = allCategories.stream()
                .collect(Collectors.toMap(RepairCategory::getId, category -> category));

        // 构建响应
        List<UserSkillSummaryResponse> responses = maintenanceUsers.stream().map(user -> {
            UserSkillSummaryResponse response = new UserSkillSummaryResponse();
            response.setUserInfo(UserConverter.toUserResponse(user));

            List<Integer> userCategoryIds = userSkillMap.getOrDefault(user.getId(), new ArrayList<>());
            List<UserSkillSummaryResponse.SkillCategoryInfo> skillInfos = userCategoryIds.stream()
                    .map(categoryId -> {
                        RepairCategory category = categoryMap.get(categoryId);
                        if (category != null) {
                            UserSkillSummaryResponse.SkillCategoryInfo skillInfo = new UserSkillSummaryResponse.SkillCategoryInfo();
                            skillInfo.setCategoryId(category.getId());
                            skillInfo.setCategoryName(category.getCategoryName());
                            skillInfo.setCategoryDescription(category.getDescription());
                            skillInfo.setIsActive(category.getIsActive());
                            return skillInfo;
                        }
                        return null;
                    })
                    .filter(skillInfo -> skillInfo != null)
                    .collect(Collectors.toList());

            response.setSkills(skillInfos);
            return response;
        }).collect(Collectors.toList());

        return BaseResponse.success(responses);
    }

    /**
     * 获取技能统计信息
     */
    @PostMapping("/stats")
    @Operation(summary = "获取技能统计信息", description = "获取维修工和技能的统计数据")
    @RequireRole(UserConstant.UserType.ADMIN)
    public BaseResponse<SkillStatsResponse> getSkillStats(HttpServletRequest request) {
        SkillStatsResponse stats = maintenanceSkillService.getSkillStats();
        return BaseResponse.success(stats);
    }

    /**
     * 转换技能实体为响应DTO
     */
    private List<MaintenanceSkillResponse> convertToSkillResponses(List<MaintenanceSkill> skills) {
        if (skills.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取用户信息
        List<Long> userIds = skills.stream().map(MaintenanceSkill::getUserId).distinct().collect(Collectors.toList());
        List<GeneralUser> users = generalUserService.listByIds(userIds);
        Map<Long, GeneralUser> userMap = users.stream().collect(Collectors.toMap(GeneralUser::getId, user -> user));

        // 获取类别信息
        List<Integer> categoryIds = skills.stream().map(MaintenanceSkill::getCategoryId).distinct().collect(Collectors.toList());
        List<RepairCategory> categories = repairCategoryService.listByIds(categoryIds);
        Map<Integer, RepairCategory> categoryMap = categories.stream().collect(Collectors.toMap(RepairCategory::getId, category -> category));

        return skills.stream().map(skill -> {
                    MaintenanceSkillResponse response = new MaintenanceSkillResponse();
                    response.setUserId(skill.getUserId());
                    response.setCategoryId(skill.getCategoryId());
                    response.setCreatedAt(skill.getCreatedAt());
                    response.setUpdatedAt(skill.getUpdatedAt());

                    // 设置用户信息
                    GeneralUser user = userMap.get(skill.getUserId());
                    if (user != null) {
                        response.setAccountName(user.getAccountName());
                        response.setNickName(user.getNickName());
                        response.setEmail(user.getEmail());
                        response.setPhoneNumber(user.getPhoneNumber());
                    }

                    // 设置类别信息
                    RepairCategory category = categoryMap.get(skill.getCategoryId());
                    if (category != null) {
                        response.setCategoryName(category.getCategoryName());
                        response.setCategoryDescription(category.getDescription());
                    }

                    return response;
                }).distinct()
                .collect(Collectors.toList());
    }
}
